﻿// Type: System.ServiceModel.DomainServices.Client.OperationBase
// Assembly: System.ServiceModel.DomainServices.Client, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Assembly location: C:\Program Files (x86)\Microsoft SDKs\RIA Services\v1.0\Libraries\Silverlight\System.ServiceModel.DomainServices.Client.dll

using System;
using System.ComponentModel;

namespace System.ServiceModel.DomainServices.Client
{
  public abstract class OperationBase : INotifyPropertyChanged
  {
    private object _result;
    private Exception _error;
    private bool _canceled;
    private bool _completed;
    private object _userState;
    private PropertyChangedEventHandler _propChangedHandler;
    private EventHandler _completedEventHandler;
    private bool _isErrorHandled;

    public bool IsErrorHandled
    {
      get
      {
        return this._isErrorHandled;
      }
    }

    protected virtual bool SupportsCancellation
    {
      get
      {
        return false;
      }
    }

    public bool CanCancel
    {
      get
      {
        if (this.SupportsCancellation)
          return !this._completed;
        else
          return false;
      }
    }

    public bool IsCanceled
    {
      get
      {
        return this._canceled;
      }
    }

    public Exception Error
    {
      get
      {
        return this._error;
      }
    }

    public bool HasError
    {
      get
      {
        return this._error != null;
      }
    }

    public bool IsComplete
    {
      get
      {
        return this._completed;
      }
    }

    protected object Result
    {
      get
      {
        return this._result;
      }
    }

    public object UserState
    {
      get
      {
        return this._userState;
      }
    }

    public event EventHandler Completed
    {
      add
      {
        if (this.IsComplete)
          value((object) this, EventArgs.Empty);
        else
          this._completedEventHandler = this._completedEventHandler + value;
      }
      remove
      {
        this._completedEventHandler = this._completedEventHandler - value;
      }
    }

    event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
    {
      add
      {
        this._propChangedHandler = this._propChangedHandler + value;
      }
      remove
      {
        this._propChangedHandler = this._propChangedHandler - value;
      }
    }

    protected OperationBase(object userState)
    {
      this._userState = userState;
    }

    public void MarkErrorAsHandled()
    {
      if (this._error == null)
        throw new InvalidOperationException(Resource.Operation_HasErrorMustBeTrue);
      if (this._isErrorHandled)
        return;
      this._isErrorHandled = true;
      this.RaisePropertyChanged("IsErrorHandled");
    }

    public void Cancel()
    {
      if (!this.SupportsCancellation)
        throw new NotSupportedException(Resources.AsyncOperation_CancelNotSupported);
      this.EnsureNotCompleted();
      this._completed = true;
      this._canceled = true;
      this.CancelCore();
      this.InvokeCompleteAction();
      if (this._completedEventHandler != null)
        this._completedEventHandler((object) this, EventArgs.Empty);
      this.RaisePropertyChanged("IsCanceled");
      this.RaisePropertyChanged("CanCancel");
      this.RaisePropertyChanged("IsComplete");
    }

    protected virtual void CancelCore()
    {
    }

    protected void Complete(object result)
    {
      this.EnsureNotCompleted();
      bool canCancel = this.CanCancel;
      this._result = result;
      this._completed = true;
      this.InvokeCompleteAction();
      if (this._completedEventHandler != null)
        this._completedEventHandler((object) this, EventArgs.Empty);
      this.RaisePropertyChanged("IsComplete");
      if (!canCancel)
        return;
      this.RaisePropertyChanged("CanCancel");
    }

    protected void Complete(Exception error)
    {
      if (error == null)
        throw new ArgumentNullException("error");
      this.EnsureNotCompleted();
      bool canCancel = this.CanCancel;
      this._error = error;
      this._completed = true;
      this.InvokeCompleteAction();
      if (this._completedEventHandler != null)
        this._completedEventHandler((object) this, EventArgs.Empty);
      this.RaisePropertyChanged("Error");
      this.RaisePropertyChanged("HasError");
      this.RaisePropertyChanged("IsComplete");
      if (canCancel)
        this.RaisePropertyChanged("CanCancel");
      if (!this.IsErrorHandled)
        throw error;
    }

    protected abstract void InvokeCompleteAction();

    private void EnsureNotCompleted()
    {
      if (this._completed)
        throw new InvalidOperationException(Resources.AsyncOperation_AlreadyCompleted);
    }

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
      if (this._propChangedHandler == null)
        return;
      this._propChangedHandler((object) this, e);
    }

    protected void RaisePropertyChanged(string propertyName)
    {
      this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }
  }
}
